package com.ibeeking.found.cop.b.rest.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.JsonObject;
import com.ibeeking.found.common.utils.UserUtils;
import com.ibeeking.found.cop.b.rest.service.*;
import com.ibeeking.found.cop.service.common.bo.MsgSendRuleBO;
import com.ibeeking.found.cop.service.common.constants.PublicParamConstant;
import com.ibeeking.found.cop.service.common.dos.*;
import com.ibeeking.found.cop.service.common.enums.*;
import com.ibeeking.found.cop.service.common.param.CopJobHandleParam;
import com.ibeeking.found.cop.service.common.param.MqSyncCopParam;
import com.ibeeking.found.cop.service.common.param.MsgFansMomentParam;
import com.ibeeking.found.cop.service.common.query.MsgFansMomentPageQuery;
import com.ibeeking.found.cop.service.common.query.MsgFansMomentQuery;
import com.ibeeking.found.cop.service.common.vo.CopAttachementVO;
import com.ibeeking.found.cop.service.common.vo.MsgFansMomentVO;
import com.ibeeking.found.cop.service.mapper.*;
import com.ibeeking.found.id.GenerateId;
import com.ibeeking.nematos.core.utils.SpringBeanUtil;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.log.utils.LogUtils;
import com.ibeeking.nematos.utils.bean.BeanUtil;
import com.ibeeking.nematos.utils.cron.TaskScheduleModel;
import com.ibeeking.nematos.utils.data.Collections3;
import com.ibeeking.nematos.utils.date.DateUtil;
import com.ibeeking.nematos.utils.id.IdGenerator;
import com.ibeeking.nematos.utils.json.JsonUtils;
import me.chanjar.weixin.common.enums.WxType;
import me.chanjar.weixin.common.error.WxError;
import me.chanjar.weixin.cp.api.WxCpExternalContactService;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl;
import me.chanjar.weixin.cp.bean.external.WxCpAddMomentResult;
import me.chanjar.weixin.cp.bean.external.WxCpAddMomentTask;
import me.chanjar.weixin.cp.bean.external.WxCpGetMomentTaskResult;
import me.chanjar.weixin.cp.bean.external.moment.ExternalContactList;
import me.chanjar.weixin.cp.bean.external.moment.SenderList;
import me.chanjar.weixin.cp.bean.external.msg.Attachment;
import me.chanjar.weixin.cp.bean.external.msg.Text;
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Consts;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @ClassName MsgFansMomentServiceImpl
 * @Description
 * @Author ibeeking
 * @Date 2021-01-27 18:50
 **/
@Service
public class MsgFansMomentServiceImpl extends ServiceImpl<MsgFansMomentMapper, MsgFansMomentDO> implements IMsgFansMomentService {

    @Resource
    private MsgFansMomentMapper msgFansMomentMapper;

    @Resource
    private MsgFansMomentTaskMapper msgFansMomentTaskMapper;

    @Resource
    private CopAttachementMapper copAttachementMapper;

    @Resource
    private CopEmployeeMapper copEmployeeMapper;

    @Resource
    private FriendsMapper friendsMapper;

    @Resource
    private FriendsTagsRelMapper friendsTagsRelMapper;

    @Resource
    private MsgFansMomentTaskSenderMapper msgFansMomentTaskSenderMapper;

    @Resource
    private MsgFansMomentTaskFriendsMapper msgFansMomentTaskFriendsMapper;

    @Resource
    private ICopPublicParamService copPublicParamServiceImpl;

    @Resource
    private ICopAttachementService copAttachementServiceImpl;

    @Resource
    private ICopJobCreateService copJobCreateServiceImpl;

    @Resource
    private IMqService mqServiceImpl;

    @Resource
    private IWxOpenService wxOpenServiceImpl;

    @Override
    public List<MsgFansMomentVO> list(MsgFansMomentQuery query) {
        List<MsgFansMomentDO> entityDOS = msgFansMomentMapper.selectList(new LambdaQueryWrapper<MsgFansMomentDO>()
                .eq(query.getId() != null, MsgFansMomentDO::getId, query.getId())
                .like(StringUtils.isNotBlank(query.getContent()), MsgFansMomentDO::getContent, query.getContent())
                .eq(query.getSendStatus() != null, MsgFansMomentDO::getSendStatus, query.getSendStatus())
                .orderByDesc(MsgFansMomentDO::getSendTime).orderByDesc(MsgFansMomentDO::getCreateTime)
        );
        List<MsgFansMomentVO> entityVOS =JsonUtils.jsonToList(entityDOS, MsgFansMomentVO.class);
        entityVOS.forEach(x -> {
            String sendRuleStr = x.getSendRule();
            if(StringUtils.isNotEmpty(sendRuleStr)){
                MsgSendRuleBO msgSendRuleBO = JsonUtils.fromJson(sendRuleStr, MsgSendRuleBO.class);
                x.setMsgSendRule(msgSendRuleBO);
            }else{
                MsgSendRuleBO msgSendRuleBO = new MsgSendRuleBO();
                x.setMsgSendRule(msgSendRuleBO);
            }
            x.setSendStatusDesc(WxCpMessageAssignStatusEnum.getDescByCode(x.getSendStatus()));
        });
        return entityVOS;
    }

    @Override
    public Page<MsgFansMomentVO> pageList(MsgFansMomentPageQuery pageQuery) {
        LambdaQueryWrapper<MsgFansMomentDO> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(pageQuery.getId() != null, MsgFansMomentDO::getId, pageQuery.getId())
                .like(StringUtils.isNotBlank(pageQuery.getContent()), MsgFansMomentDO::getContent, pageQuery.getContent())
                .eq(pageQuery.getSendStatus() != null, MsgFansMomentDO::getSendStatus, pageQuery.getSendStatus())
                .orderByDesc(MsgFansMomentDO::getSendTime).orderByDesc(MsgFansMomentDO::getCreateTime);
        Page<MsgFansMomentDO> entityDOPages = msgFansMomentMapper.selectPage(new Page<MsgFansMomentDO>(pageQuery.getPageNum(), pageQuery.getPageSize()), wrapper);
        Page<MsgFansMomentVO> entityVOPages = BeanUtil.convertPage(entityDOPages, MsgFansMomentVO.class);
        entityVOPages.getRecords().forEach(f ->{
            String sendRuleStr = f.getSendRule();
            if(StringUtils.isNotEmpty(sendRuleStr)){
                MsgSendRuleBO msgSendRuleBO = JsonUtils.fromJson(sendRuleStr, MsgSendRuleBO.class);
                f.setMsgSendRule(msgSendRuleBO);
            }else{
                MsgSendRuleBO msgSendRuleBO = new MsgSendRuleBO();
                f.setMsgSendRule(msgSendRuleBO);
            }
            f.setSendStatusDesc(WxCpMessageAssignStatusEnum.getDescByCode(f.getSendStatus()));
        });
        return entityVOPages;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean add(MsgFansMomentParam param) {
        MsgFansMomentDO entityDO = BeanUtil.convertBean(param, MsgFansMomentDO.class);
        Long msgId = GenerateId.generateId();
        entityDO.setId(msgId);
        entityDO.setVisibleType(WxCpMomentVisibleTypeEnum.MOMENT_VISIBLE_TYPE_ALL.getCode());
        entityDO.setCreateBy(UserUtils.getUserId());
        entityDO.setCreateTime(LocalDateTime.now());
        entityDO.setModifyTime(LocalDateTime.now());
        MsgSendRuleBO msgSendRuleBO = param.getMsgSendRule();
        if(msgSendRuleBO != null){
            entityDO.setSendRule(JsonUtils.toJsonStr(msgSendRuleBO));
        }
        Integer sendWay = param.getSendWay();
        if(sendWay == WxCpMessageSendWayEnum.MESSAGE_SEND_WAY_TASK.getCode()){
            String sendTimeStr = param.getSendTime();
            if(StringUtils.isEmpty(sendTimeStr)) throw new BusinessException("选择定时发送时候，必须设置任务时间！");
            LocalDateTime sendTime = DateUtil.strToLocalDateTime(sendTimeStr);
            if(sendTime!=null){
                entityDO.setSendTime(sendTime);
            }
        }
        return msgFansMomentMapper.insert(entityDO) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean modify(MsgFansMomentParam param) {
        MsgFansMomentDO entityDO = BeanUtil.convertBean(param, MsgFansMomentDO.class);
        entityDO.setModifyBy(UserUtils.getUserId());
        entityDO.setModifyTime(LocalDateTime.now());
        MsgSendRuleBO msgSendRuleBO = param.getMsgSendRule();
        if(msgSendRuleBO != null){
            entityDO.setSendRule(JsonUtils.toJsonStr(msgSendRuleBO));
        }
        Integer sendWay = param.getSendWay();
        if(sendWay == WxCpMessageSendWayEnum.MESSAGE_SEND_WAY_TASK.getCode()){
            String sendTimeStr = param.getSendTime();
            if(StringUtils.isEmpty(sendTimeStr)) throw new BusinessException("选择定时发送时候，必须设置任务时间！");
            LocalDateTime sendTime = DateUtil.strToLocalDateTime(sendTimeStr);
            if(sendTime!=null){
                entityDO.setSendTime(sendTime);
            }
        }
        return msgFansMomentMapper.updateById(entityDO) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean updateBatch(List<MsgFansMomentDO> entityDOList) {
        return super.updateBatchById(entityDOList);
    }

    @Override
    public Boolean copy(Long id) {
        MsgFansMomentDO entityDO = msgFansMomentMapper.selectById(id);
        if(entityDO == null) throw new BusinessException("没有查到相关记录！");
        Long newId = IdGenerator.getId();
        entityDO.setId(newId);
        entityDO.setCreateTime(LocalDateTime.now());
        entityDO.setModifyTime(LocalDateTime.now());
        entityDO.setSendCycle(0);
        if(entityDO.getSendWay() == 1){
            entityDO.setSendTime(null);
        }
        entityDO.setRtnJobId(null);
        entityDO.setRtnMomentId(null);
        entityDO.setSendStatus(WxCpMessageAssignStatusEnum.MESSAGE_ASSIGN_STATUS_NOASSIGN.getCode());
        entityDO.setBuidTime(null);
        List<CopAttachementDO> copAttachementDOList = copAttachementMapper.selectList(new LambdaQueryWrapper<CopAttachementDO>().eq(CopAttachementDO::getMessageId,id));
        if(Collections3.isNotEmpty(copAttachementDOList)){
            copAttachementDOList.parallelStream().forEach(d->{
                d.setMessageId(newId);
                d.setId(IdGenerator.getId());
                d.setCreateTime(LocalDateTime.now());
                d.setModifyTime(LocalDateTime.now());
            });
            copAttachementMapper.insertBatchSomeColumn(copAttachementDOList);
        }
        msgFansMomentMapper.insert(entityDO);
        return true;
    }

    @Override
    public MsgFansMomentVO view(Long id) {
        MsgFansMomentDO entityDO = msgFansMomentMapper.selectById(id);
        if(entityDO == null) throw new BusinessException("没有查到相关记录！");
        MsgFansMomentVO entityVO = BeanUtil.convertBean(entityDO, MsgFansMomentVO.class);
        if(entityVO != null) {
            LocalDateTime sentTime = entityDO.getSendTime();
            if(sentTime!=null){
                entityVO.setSendTime(DateUtil.localDateTimeToStr(sentTime));
            }
            String sendRuleStr = entityVO.getSendRule();
            if(StringUtils.isNotEmpty(sendRuleStr)){
                MsgSendRuleBO msgSendRuleBO = JsonUtils.fromJson(sendRuleStr, MsgSendRuleBO.class);
                entityVO.setMsgSendRule(msgSendRuleBO);
            }else{
                MsgSendRuleBO msgSendRuleBO = new MsgSendRuleBO();
                entityVO.setMsgSendRule(msgSendRuleBO);
            }
            entityVO.setSendStatusDesc(WxCpMessageAssignStatusEnum.getDescByCode(entityDO.getSendStatus()));
        }
        return entityVO;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean changeStatus(Long id, Integer status) {
        MsgFansMomentDO entityDO = msgFansMomentMapper.selectById(id);
        if(entityDO == null) throw new BusinessException("没有查到相关记录！");
        entityDO.setSendStatus(status);
        entityDO.setModifyBy(UserUtils.getUserId());
        entityDO.setModifyTime(LocalDateTime.now());
        return msgFansMomentMapper.updateById(entityDO) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean del(Long id) {
        MsgFansMomentDO entityDO = msgFansMomentMapper.selectById(id);
        if(entityDO == null) throw new BusinessException("没有查到相关记录！");
        return msgFansMomentMapper.deleteById(id) > 0;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean sendWxCpFansMoment(Long id) {
        String tenantId = UserUtils.getTenantId();
        MsgFansMomentDO entityDO = msgFansMomentMapper.selectById(id);
        if(entityDO == null) throw new BusinessException("没有查到相关记录！");
        Long msgId = entityDO.getId();
        Integer sendWay = entityDO.getSendWay();
        if(sendWay == 2){
            LocalDateTime sendTime = entityDO.getSendTime();
            if(sendTime.isBefore(LocalDateTime.now())) throw new BusinessException("已经过了定时发送时间，请重新设置定时发送时间！");
            if(sendTime != null) {
                TaskScheduleModel scheduleModel = new TaskScheduleModel();
                scheduleModel.setJobType(6);
                scheduleModel.setSecond(sendTime.getSecond());
                scheduleModel.setMinute(sendTime.getMinute());
                scheduleModel.setDay(sendTime.getDayOfMonth());
                scheduleModel.setMonth(sendTime.getMonthValue());
                scheduleModel.setFromYear(sendTime.getYear());
                scheduleModel.setToYear(sendTime.getYear());
                CopJobHandleParam handleParam = new CopJobHandleParam();
                handleParam.setId(msgId);
                handleParam.setTenantId(Integer.valueOf(tenantId));
                copJobCreateServiceImpl.createJobInfoForSendGroupMassMessage(Integer.valueOf(tenantId), scheduleModel, handleParam);
            }
        }else{
            this.getBean().sendFansMomentToWxCp(Integer.valueOf(tenantId), msgId);
        }
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean stopWxCpFansMoment(Long id) {
        String tenantId = UserUtils.getTenantId();
        MqSyncCopParam mqParam = new MqSyncCopParam();
        mqParam.setOperType(MqSyncOperatorTypeEnum.COP_SYNC_STOP_FANS_MOMENT.getCode());
        mqParam.setTenantId(Long.valueOf(tenantId));
        mqParam.setId(id);
        mqServiceImpl.sendSyncToWxTaskMessage(mqParam);
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean refreshWxCpFansMomentPublishRecord() {
        String tenantId = UserUtils.getTenantId();
        MqSyncCopParam mqParam = new MqSyncCopParam();
        mqParam.setOperType(MqSyncOperatorTypeEnum.COP_SYNC_FANS_MOMENT_PUBLISH_RECORD.getCode());
        mqParam.setTenantId(Long.valueOf(tenantId));
        String beforeRefreshDate = copPublicParamServiceImpl.getParamValue(PublicParamConstant.FANS_MOMENT_RECORD_LAST_REFRESH_DATE);
        LocalDateTime nowDate = LocalDateTime.now();
        if(StringUtils.isEmpty(beforeRefreshDate)){
            mqParam.setBeginDate(DateUtil.localDateTimeToStr(nowDate.minusDays(29)));
        }else{
            mqParam.setBeginDate(beforeRefreshDate);
        }
        mqParam.setEndDate(DateUtil.localDateTimeToStr(nowDate));
        mqServiceImpl.sendSyncToWxTaskMessage(mqParam);
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean sendFansMomentToWxCp(Integer tenantId, Long messageId) {
        if(messageId == null) throw new BusinessException("发送任务获取消息参数messageId为空");
        MsgFansMomentDO momentDO = msgFansMomentMapper.selectById(messageId);
        if(momentDO == null) throw new BusinessException("通过msgId获得的消息数据为空!");
        int sendCycle = momentDO.getSendCycle();
        String sendRules = momentDO.getSendRule();
        MsgFansMomentTaskDO momentTaskDO = new MsgFansMomentTaskDO();
        momentTaskDO.setId(IdGenerator.getId());
        momentTaskDO.setType(WxCpMessageTypeEnum.MESSAGE_MOMENT_TYPE_ADD_TASK.getCode());
        momentTaskDO.setMomentId(momentDO.getId());
        momentTaskDO.setSendWay(momentDO.getSendWay());
        if(momentDO.getSendWay() == WxCpMessageSendWayEnum.MESSAGE_SEND_WAY_TASK.getCode()){
            momentTaskDO.setSendTime(momentDO.getSendTime());
        }else {
            momentTaskDO.setSendTime(LocalDateTime.now());
            momentDO.setSendTime(LocalDateTime.now());
        }
        List<String> allSenderList = new ArrayList<>();
        List<String> allValidSenderList = new ArrayList<>();
        List<String> allReciverList = new ArrayList<>();
        List<String> allValidReciverList = new ArrayList<>();
        List<MsgFansMomentTaskSenderDO> allValidSenderDOList = new ArrayList<>();
        List<MsgFansMomentTaskFriendsDO> allValidFriendsDOList = new ArrayList<>();
        if(StringUtils.isNotEmpty(sendRules)){
            MsgSendRuleBO msgSendRuleBO = JsonUtils.fromJson(sendRules, MsgSendRuleBO.class);
            allSenderList = collectAllSenders(tenantId, msgSendRuleBO);
            allReciverList = collectAllNeedSendFriends(tenantId, msgSendRuleBO);
        }

        try {
            WxCpService wxCpService = wxOpenServiceImpl.getWxCpService(tenantId.longValue());
            WxCpConfigStorage wxCpConfigStorage = wxCpService.getWxCpConfigStorage();
            if (wxCpConfigStorage == null) {
                throw new BusinessException("获取企微服务失败!");
            }

            WxCpExternalContactService wxCpExternalContactService = wxCpService.getExternalContactService();
            if (wxCpExternalContactService == null) throw new BusinessException("获取企微服务外部联系人服务!");

            WxCpAddMomentTask wxCpAddMomentTask = new WxCpAddMomentTask();
            wxCpAddMomentTask.setVisibleRange(null);
            me.chanjar.weixin.cp.bean.external.msg.Text msgText = new Text();
            msgText.setContent(momentDO.getContent());
            wxCpAddMomentTask.setText(msgText);
            //添加附件
            CopAttachementVO copAttachementVO = copAttachementServiceImpl.queryByMessageId(messageId);
            if(null != copAttachementVO) {
                //先把消息中的附件同步到企微
                copAttachementServiceImpl.syncMessageAttachementsToWxCp(messageId);
                List<CopAttachementVO> copAttachementVOS = new ArrayList<>();
                copAttachementVOS.add(copAttachementVO);
                List<Attachment>  attachementList = copAttachementServiceImpl.transerCopAttachementToWxcpAttachement(copAttachementVOS);
                wxCpAddMomentTask.setAttachments(attachementList);
            }
            WxCpAddMomentResult wxCpAddMomentResult = wxCpExternalContactService.addMomentTask(wxCpAddMomentTask);
            LogUtils.info("====process WxCpAddMomentResult:{}====", JsonUtils.toJsonStr(wxCpAddMomentResult));
            if(Collections3.isNotEmpty(allSenderList)){
                momentTaskDO.setTotalSenderList(JsonUtils.toJsonStr(allSenderList));
            }
            if(Collections3.isNotEmpty(allReciverList)){
                momentTaskDO.setTotalFriendsList(JsonUtils.toJsonStr(allReciverList));
            }
            if(wxCpAddMomentResult !=null && wxCpAddMomentResult.getErrcode() == 0){
                String rtJobId = wxCpAddMomentResult.getJobId();
                if(StringUtils.isNotEmpty(rtJobId)) {

                    WxCpGetMomentTaskResult wxCpGetMomentTaskResult = wxCpExternalContactService.getMomentTaskResult(rtJobId);
                    LogUtils.info("====process wxCpGetMomentTaskResult:{}====", JsonUtils.toJsonStr(wxCpGetMomentTaskResult));
                    if(wxCpGetMomentTaskResult!=null && wxCpGetMomentTaskResult.getErrcode() == 0) {
                        String taskType = wxCpGetMomentTaskResult.getType();
                        momentTaskDO.setType(taskType);
                        Integer taskStatus = wxCpGetMomentTaskResult.getStatus();
                        momentTaskDO.setTaskStatus(taskStatus);
                        WxCpGetMomentTaskResult.TaskResult taskResult = wxCpGetMomentTaskResult.getResult();
                        if(taskResult!=null) {
                            String momentCode = taskResult.getMomentId();
                            momentDO.setRtnMomentId(momentCode);
                            momentTaskDO.setRtnMomentCode(momentCode);
                            SenderList invalidSenderList = taskResult.getInvalidSenderList();
                            ExternalContactList externalContactList = taskResult.getInvalidExternalContactList();
                            if(invalidSenderList!=null) {
                                List<String> invalidSenderCodeList = invalidSenderList.getUserList();
                                List<String> invalidSenderPartyList = invalidSenderList.getDepartmentList(); //暂时不用
                                if (Collections3.isNotEmpty(invalidSenderCodeList)) {
                                    momentTaskDO.setInvalidSenderList(JsonUtils.toJsonStr(invalidSenderCodeList));
                                    HashSet<String> allSenderHashset = new HashSet<>(allSenderList);
                                    HashSet<String> invalidSenderHashset = new HashSet<>(invalidSenderCodeList);
                                    if (allSenderHashset.removeAll(invalidSenderHashset)) {
                                        allValidSenderList = new ArrayList<>(allSenderHashset);
                                        momentTaskDO.setValidSenderList(JsonUtils.toJsonStr(allValidSenderList));
                                        if(Collections3.isNotEmpty(allValidSenderList)){
                                            List<CopEmployeeDO> copEmployeeDOS = copEmployeeMapper.selectList(new LambdaQueryWrapper<>());
                                            Map<String, Long> copEmployeeNameMaps = Collections3.isNotEmpty(copEmployeeDOS)?copEmployeeDOS.stream().collect(Collectors.toMap(CopEmployeeDO::getEmployeeCode, CopEmployeeDO::getId, (o, n) -> n)):null;

                                            for(String senderCode : allValidSenderList){
                                                MsgFansMomentTaskSenderDO msgFansMomentTaskSenderDO = new MsgFansMomentTaskSenderDO();
                                                msgFansMomentTaskSenderDO.setId(IdGenerator.getId());
                                                msgFansMomentTaskSenderDO.setJobId(rtJobId);
                                                msgFansMomentTaskSenderDO.setMomentId(momentDO.getId());
                                                msgFansMomentTaskSenderDO.setTaskId(momentTaskDO.getId());
                                                msgFansMomentTaskSenderDO.setMomentCode(momentCode);
                                                if(StringUtils.isNotEmpty(senderCode)) {
                                                    msgFansMomentTaskSenderDO.setSenderId(copEmployeeNameMaps!=null?copEmployeeNameMaps.get(senderCode):null);
                                                    msgFansMomentTaskSenderDO.setSenderCode(senderCode);
                                                }
                                                msgFansMomentTaskSenderDO.setPublishStatus(0);
                                                allValidSenderDOList.add(msgFansMomentTaskSenderDO);
                                            }
                                        }
                                    }
                                }
                            }
                            if(externalContactList!=null) {
                                List<String> invalidFriendsCodeList = externalContactList.getTagList();
                                if (Collections3.isNotEmpty(invalidFriendsCodeList)) {
                                    momentTaskDO.setInvalidFriendsList(JsonUtils.toJsonStr(invalidFriendsCodeList));
                                    HashSet<String> allFriendsHashset = new HashSet<>(allReciverList);
                                    HashSet<String> invalidFriendsHashset = new HashSet<>(invalidFriendsCodeList);
                                    if (allFriendsHashset.removeAll(invalidFriendsHashset)) {
                                        allValidReciverList = new ArrayList<>(allFriendsHashset);
                                        momentTaskDO.setValidFriendsList(JsonUtils.toJsonStr(allValidReciverList));
                                        if(Collections3.isNotEmpty(allValidReciverList)) {
                                            for (String friendsCode : allValidReciverList) {
                                                MsgFansMomentTaskFriendsDO msgFansMomentTaskFriendsDO = new MsgFansMomentTaskFriendsDO();
                                                msgFansMomentTaskFriendsDO.setId(IdGenerator.getId());
                                                msgFansMomentTaskFriendsDO.setJobId(rtJobId);
                                                msgFansMomentTaskFriendsDO.setMomentId(momentDO.getId());
                                                msgFansMomentTaskFriendsDO.setTaskId(momentTaskDO.getId());
                                                msgFansMomentTaskFriendsDO.setMomentCode(momentCode);
                                                msgFansMomentTaskFriendsDO.setFriendsCode(friendsCode);
                                                allValidFriendsDOList.add(msgFansMomentTaskFriendsDO);
                                            }
                                        }
                                    }
                                }
                            }
                            momentDO.setRtnJobId(rtJobId);
                            momentDO.setSendStatus(WxCpMessageAssignStatusEnum.MESSAGE_ASSIGN_STATUS_ASSIGNED.getCode());
                            momentDO.setSendCycle(sendCycle + 1);
                            momentTaskDO.setRtnJobId(rtJobId);

                        }
                    }
                }
            }else{
                momentDO.setSendStatus(WxCpMessageAssignStatusEnum.MESSAGE_ASSIGN_STATUS_ASSIGNED.getCode());
                momentTaskDO.setInvalidSenderList(JsonUtils.toJsonStr(allSenderList));
                momentTaskDO.setInvalidFriendsList(JsonUtils.toJsonStr(allReciverList));
            }
        } catch (Exception e) {
            LogUtils.error("发送消息异常:{}", e);
            momentDO.setSendStatus(WxCpMessageAssignStatusEnum.MESSAGE_ASSIGN_STATUS_ASSIGNED.getCode());
            momentTaskDO.setInvalidSenderList(JsonUtils.toJsonStr(allSenderList));
            momentTaskDO.setInvalidFriendsList(JsonUtils.toJsonStr(allReciverList));
            momentTaskDO.setRemark("发送消息失败!");
        }
        LogUtils.info("====process momentDO:{}====", JsonUtils.toJsonStr(momentDO));
        if(momentDO!=null){
            msgFansMomentMapper.updateById(momentDO);
        }
        LogUtils.info("====process momentTaskDO:{}====", JsonUtils.toJsonStr(momentTaskDO));
        if(momentTaskDO !=null){
            msgFansMomentTaskMapper.insert(momentTaskDO);
        }
        LogUtils.info("====process allValidSenderDOList:{}====", JsonUtils.toJsonStr(allValidSenderDOList));
        if(Collections3.isNotEmpty(allValidSenderDOList)){
            msgFansMomentTaskSenderMapper.insertBatchSomeColumn(allValidSenderDOList);
        }
        LogUtils.info("====process allValidReciverList:{}====", JsonUtils.toJsonStr(allValidReciverList));
        if(Collections3.isNotEmpty(allValidReciverList)){
            msgFansMomentTaskFriendsMapper.insertBatchSomeColumn(allValidFriendsDOList);
        }
        return true;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Boolean stopSendFansMomentToWxCp(Integer tenantId, Long momentId) {
        if(momentId == null) throw new BusinessException("发送任务获取消息参数momentId为空");
        MsgFansMomentDO momentDO = msgFansMomentMapper.selectById(momentId);
        if(momentDO == null) throw new BusinessException("通过momentId获得的消息数据为空!");
        String rtnMomentId = momentDO.getRtnMomentId();
        if(StringUtils.isNotEmpty(rtnMomentId)){
            Boolean result = askWxCpToStopSendFansMoment(tenantId.toString(), rtnMomentId);
            if(result){
                momentDO.setSendStatus(WxCpMessageAssignStatusEnum.MESSAGE_ASSIGN_STATUS_CANCEL.getCode());
                msgFansMomentMapper.updateById(momentDO);
            }
        }
        return true;
    }

    /**
     * 基于消息的发送规则收集所有需要发送的客户或客户群Code清单
     *
     * @param msgSendRule
     */
    private List<String> collectAllSenders(Integer tenantId,MsgSendRuleBO msgSendRule){
        if(msgSendRule!=null){
            List<String> allSenderCodes = new ArrayList<>();
            Integer allEmployees = msgSendRule.getIsAllEmployee();
            if(allEmployees!=null && allEmployees == 1){
                List<CopEmployeeDO> allEmployeeDOS = copEmployeeMapper.selectList(new LambdaQueryWrapper<CopEmployeeDO>().isNotNull(CopEmployeeDO::getEmployeeCode));
                if(Collections3.isNotEmpty(allEmployeeDOS)) {
                    List<String> allEmployeeCodes = allEmployeeDOS.parallelStream().map(CopEmployeeDO::getEmployeeCode).collect(Collectors.toList());
                    allSenderCodes.addAll(allEmployeeCodes);
                }
            }
            List<String> selectedEmployeeCodes = msgSendRule.getEmployeeCodeList();
            if(Collections3.isNotEmpty(selectedEmployeeCodes)){
                allSenderCodes.addAll(selectedEmployeeCodes);
            }
            return allSenderCodes;
        }
        return null;
    }

    /**
     * 基于消息的发送规则收集所有需要发送的客户或客户群Code清单
     *
     * @param msgSendRule
     */
    private List<String> collectAllNeedSendFriends(Integer tenantId,MsgSendRuleBO msgSendRule){
        if(msgSendRule!=null){
            List<String> allReceiverCodes = new ArrayList<>();
            Integer allFriends = msgSendRule.getIsAllFriends();
            if(allFriends!=null && allFriends == 1){
                List<FriendsDO> allFriendsDOS = friendsMapper.selectList(new LambdaQueryWrapper<FriendsDO>().isNotNull(FriendsDO::getFriendsCode));
                if(Collections3.isNotEmpty(allFriendsDOS)) {
                    List<String> allFriendsCodes = allFriendsDOS.parallelStream().map(FriendsDO::getFriendsCode).collect(Collectors.toList());
                    allReceiverCodes.addAll(allFriendsCodes);
                }
            }

            List<String> selectedFriendsCodes = msgSendRule.getFriendsCodeList();
            if(Collections3.isNotEmpty(selectedFriendsCodes)){
                allReceiverCodes.addAll(selectedFriendsCodes);
            }
            List<Long> selectedFriendsTags = msgSendRule.getFriendsTagsList();
            if(Collections3.isNotEmpty(selectedFriendsTags)){
                allReceiverCodes.addAll(selectedFriendsCodes);
            }
            return allReceiverCodes;
        }
        return null;
    }

    private Boolean askWxCpToStopSendFansMoment(String tenantId, String momentCode){
        try {
            String getFollowUserUrl = "/cgi-bin/externalcontact/cancel_moment_task?access_token=%s";
            WxCpServiceImpl wxCpService = (WxCpServiceImpl)wxOpenServiceImpl.getWxCpService(Long.valueOf(tenantId));
            WxCpConfigStorage wxCpConfigStorage = wxCpService.getWxCpConfigStorage();
            if (wxCpConfigStorage == null) {
                throw new BusinessException("获取企微服务失败!");
            }
            String url = String.format(wxCpConfigStorage.getApiUrl(getFollowUserUrl),wxCpConfigStorage.getAccessToken());
            try {
                HttpPost httpPost = new HttpPost(url);
                JsonObject jsonObject = new JsonObject();
                jsonObject.addProperty("moment_id", momentCode);
                StringEntity entity = new StringEntity(jsonObject.toString(), Consts.UTF_8);
                httpPost.setEntity(entity);

                String resultContent;
                try (CloseableHttpClient httpClient = wxCpService.getRequestHttpClient();
                     CloseableHttpResponse response = httpClient.execute(httpPost)) {
                    resultContent = new BasicResponseHandler().handleResponse(response);
                } finally {
                    httpPost.releaseConnection();
                }
                WxError error = WxError.fromJson(resultContent, WxType.CP);
                if (error.getErrorCode() != 0) {
                    LogUtils.error("取消发送任务失败，原因：{}",error.getErrorMsg());
                    return false;
                }else{
                    return true;
                }
            } catch (IOException e) {
                LogUtils.error("取消发送任务失败，原因：{}",e);
                return false;
            }
        }catch(Exception ex){
            return false;
        }
    }

    /**
     * 校验唯一性
     *
     * @param param
     */
    public void checkUnique(MsgFansMomentParam param) {
        if (param == null) {
            throw new BusinessException("当前记录不存在!");
        }
        //code name确保等级唯一性
        LambdaQueryWrapper<MsgFansMomentDO> queryWrapper = new LambdaQueryWrapper<MsgFansMomentDO>()
                .ne(param.getId() != null, MsgFansMomentDO::getId, param.getId())
                .eq(MsgFansMomentDO::getContent, param.getContent());
        List<MsgFansMomentDO> dos = msgFansMomentMapper.selectList(queryWrapper);
        if (Collections3.isNotEmpty(dos)) {
            throw new BusinessException("已经存在同名的记录!");
        }
    }
    private IMsgFansMomentService getBean(){
        return SpringBeanUtil.getBean(MsgFansMomentServiceImpl.class);
    }
}
